
from xml.dom.minidom import parse

import kmeans
import clusterisationTaille
import clusterisationChaines
import clusterisationStructure
import matrice_distances
import qualite_clusterisation
import resultats


def build(xmlfile):
	#implementation de l'hypercube stockant les donnees issues de l'analyse syntaxique du xml
	
	#initialisation des tables representees par des dictionnaires dont les cles representent les dimensions
	structure={'id_structure':[],'nb_helices':[],'nb_feuillets':[],'nb_coudes':[],'nb_cysteines':[]}
	chaine={'id_chaine':[],'sequence':[]}
	proteine={'id_structure':[],'id_chaine':[],'id_proteine':[],'nb_chaines':[],'longueur':[]}
	proprietes={'AA_hydrophobes':[],'pI':[],'id_proteine':[]}
	
	cpt_structure=0
	cpt_chaine=0
	xml=parse (xmlfile)
	
	#remplissage des tables 
	for node in xml.getElementsByTagName('molecule'):
		proteine['id_proteine'] .append( node.getElementsByTagName('header')[0].childNodes[0].nodeValue)
		proteine['nb_chaines'] .append( node.getElementsByTagName('nb_chain')[0].childNodes[0].nodeValue)
		proteine['longueur'] .append( node.getElementsByTagName('size')[0].childNodes[0].nodeValue)
		proteine['id_structure'] .append( cpt_structure)
		
		proprietes['AA_hydrophobes'] .append( node.getElementsByTagName('percent_of_AA_hydrophobes')[0].childNodes[0].nodeValue)
		proprietes['pI'] .append( node.getElementsByTagName('pI')[0].childNodes[0].nodeValue)
		proprietes['id_proteine'] .append( node.getElementsByTagName('header')[0].childNodes[0].nodeValue)
		
		structure['id_structure'] .append( cpt_structure)
		structure['nb_helices'] .append( node.getElementsByTagName('helices')[0].childNodes[0].nodeValue)
		structure['nb_feuillets'] .append( node.getElementsByTagName('sheets')[0].childNodes[0].nodeValue)
		structure['nb_coudes'] .append( node.getElementsByTagName('turns')[0].childNodes[0].nodeValue)
		structure['nb_cysteines'] .append( node.getElementsByTagName('cysteines')[0].childNodes[0].nodeValue)
		cpt_structure=cpt_structure+1
		
		seqs=[]
		for seq in node.getElementsByTagName('sequences')[0].childNodes:
			chaine['id_chaine'] .append( cpt_chaine)
			seqs.append(cpt_chaine)
			chaine['sequence'] .append( node.getElementsByTagName('sequence')[0].childNodes[0].nodeValue)
			cpt_chaine=cpt_chaine+1
		proteine['id_chaine'].append(seqs)
		
	#retour de l'hypercube sous forme d'un dictionnaire de tables
	return {"structure":structure,"proteine":proteine,"proprietes":proprietes,"chaine":chaine}



def premierCluster(cube):
	#renvoi un tableau contenant tous les indices des proteines
	tab = []
	for i in range(len(cube["proteine"]["id_proteine"])):
		tab.append(i)
	return [x for x in tab]
	
def clusterisationK (clustersDepart, cube, nbClusters, nbIterations,  table, dimension):
	#effectue une clusterisation par la fonction kmeans
	clustersFin=[]
	for cluster in clustersDepart : 
		if nbClusters<len(cluster):
			c = kmeans.compute(cluster,  nbClusters,  nbIterations, cube, table, dimension)
			for groupe in c : 
				clustersFin.append(groupe)
		else:
			clustersFin.append(cluster)
	return clustersFin
	
def clusterisationT (clustersDepart, cube):
	#effectue une clusterisation par la taille
	clustersFin=[]
	for cluster in clustersDepart :
		if len(cluster)>6: 
			c = clusterisationTaille.clusterisationTaille(cluster, cube)
			for groupe in c : 
				clustersFin.append(groupe)
		else:
			clustersFin.append(cluster)
	return clustersFin
	
def clusterisationC (clustersDepart, cube):
	#effectue une clusterisation par le nombre de chaines
	clustersFin=[]
	for cluster in clustersDepart :
		if len(cluster)>2: 
			c = clusterisationChaines.clusterisationChaines(cluster, cube)
			for groupe in c : 
				clustersFin.append(groupe)
		else:
			clustersFin.append(cluster)
	return clustersFin
	
def clusterisationS (clustersDepart, cube):
	#effectue une clusterisation basee sur la structure secondaire
	clustersFin=[]
	for cluster in clustersDepart :	
		if len(cluster)>2: 
			c = clusterisationStructure.clusterisationStructure(cluster, cube)
			for groupe in c : 
				clustersFin.append(groupe)
		else:
			clustersFin.append(cluster)
	return clustersFin
	
	
	# Main	
if  __name__=="__main__":
	cube1 = build('xmltest_pdb.xml')
	clusters = premierCluster(cube1)
	
	#pI-longueur-hydrophobe-chaine-structure
	#~ clusterspI = kmeans.compute(clusters,  3, 51, cube1, "proprietes", "pI")
	#~ clusterLongueur = clusterisationT (clusterspI, cube1)	
	#~ clustersHydrophobe = clusterisationK(clusterLongueur,cube1,  3, 51,  "proprietes", "AA_hydrophobes")
	#~ clusterChaine = clusterisationC(clustersHydrophobe, cube1)
	#~ clusterStructure = clusterisationS(clusterChaine, cube1)
	#~ -1.1576967875       0.000116506195756
	
	
	#pi-hydro-loong-chaine-struct
	#~ clusterspI = kmeans.compute(clusters,  3, 51, cube1, "proprietes", "pI")
	#~ clustersHydrophobe = clusterisationK(clusterspI,cube1,  3, 51,  "proprietes", "AA_hydrophobes")
	#~ clusterLongueur = clusterisationT (clustersHydrophobe, cube1)
	#~ clusterChaine = clusterisationC(clusterLongueur, cube1)
	#~ clusterStructure = clusterisationS(clusterChaine, cube1)
	#~ for i  in  range(len(clusterStructure)):
		#~ print len(clusterStructure[i])
	#~ clustersCys = clusterisationK(clusterStructure,cube1,  3, 51,  "structure", "nb_cysteines")	
	#~ for i  in  range(len(clustersCys)):
		#~ print len(clustersCys[i])
	#~ -1.12572674665      0.000135039935439
	
	
	#~ #hydro-struc-chaine-pi-long
	#~ clustersHydrophobe = kmeans.compute(clusters,  3, 51, cube1, "proprietes","AA_hydrophobes")
	#~ clusterStructure = clusterisationS(clustersHydrophobe, cube1)
	#~ clusterChaine = clusterisationC(clusterStructure, cube1)

	#~ clusterspI = clusterisationK(clusterChaine, cube1,  3, 51, "proprietes", "pI")
	
	#~ clusterLongueur = clusterisationT (clusterspI, cube1)
	#~ -0.796167065638 9.28934515926e-05 pouRRRi
	
	#strategie top down
	clustersHydrophobe = kmeans.compute(clusters,  3, 51, cube1, "proprietes", "AA_hydrophobes")
	clusterLongueur = clusterisationT (clustersHydrophobe, cube1)
	clusterspI = clusterisationK(clusterLongueur,cube1,  3, 51,  "proprietes", "pI")
	clusterChaine = clusterisationC(clusterspI, cube1)
	clusterStructure = clusterisationS(clusterChaine, cube1)
		#~ -0.781572292003 0.000147593185289

	#ecriture des resultats 
	resultats.resultats(cube1,clusterStructure)
	
	#strategie bottom up
	distances=matrice_distances.matrice_generale(cube1)
	m_intra, m_inter =  qualite_clusterisation.qualite_clusterisation(distances, clusterStructure)
	print(m_intra,m_inter)
	
	
	